<?php

/*
	This file is part of Mandragon.

    Mandragon is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Mandragon is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Mandragon.  If not, see <http://www.gnu.org/licenses/>.
*/

class Menu {

	private $menu;
	private $db_access;
	private $toolbox;

	public function __construct() {
		$this->db_access = new DbAccessor();
		$this->toolbox = new Toolbox();
	}

	public function generate() {
		
		$this->menu = array();
		$menu_dirs = $this->get_directories();

		if ($_SESSION['user_id']) {
			$menu_items = $this->get_menu_items();
			$menu_reads = $this->check_what_has_been_read_if_logged_in();
		}

		$menu_access = $this->get_access_restrictions();
		
		$row_access = $this->db_access->db_fetch_array($menu_access);
		$this->menu[0]['access'] = "ALLOW";
		$this->menu[0]['children'] = array();
		
		while ($row = $this->db_access->db_fetch_array($menu_dirs)) {
			$this->add_plain_info($row);
			$this->add_ignore_info($row, $ignored); //TODO: check where the original $ignored variable has gone off to.
													//		it's disappeared.
			$this->add_access_info($row, $row_access, $menu_access);
			$this->add_to_parent_dir($row);
		}
		
		$this->add_parents();
				
		if ($_SESSION['user_id']) {
			$this->add_what_has_been_read_info($menu_reads, $menu_items);
			$this->add_ignore_info2();
		}
		return $this->menu;
	}

	private function get_directories() {
		$order = "DIRECTORY_TREE.parent_id ASC, DIRECTORY_TREE.rank ASC";
		
		$group = "DIRECTORY_TREE.child_id, DIRECTORY_TREE.parent_id";
		
		$sql = $this->db_access->db_query_select(array(array(), "DIRECTORY.*, DIRECTORY_TREE.*"), array("DIRECTORY_TREE INNER JOIN DIRECTORY ON child_id = dir_id", "DUMMY"), 
												  1, $order, "", $group);

		return $this->db_access->db_do_query($sql);
	}

	private function get_menu_items() {
		$menu_items = $this->db_access->db_do_query($this->db_access->db_query_select(array(array(), "child_id, COUNT(item_id) AS items"), 
										  array("((DIRECTORY_TREE INNER JOIN SUB_IN ON child_id = dir_id) INNER JOIN ITEM_IN " .
									"ON SUB_IN.sub_id = ITEM_IN.sub_id)", "DUMMY"), "deleted != 1", $order, "", $group));
		return $menu_items;
	}

	private function check_what_has_been_read_if_logged_in() {
		$menu_reads = $this->db_access->db_do_query($this->db_access->db_query_select(array(array(), "child_id, COUNT(HAS_READ.item_id) AS read_count"), 
							  array("((DIRECTORY_TREE INNER JOIN SUB_IN ON child_id = dir_id) INNER JOIN ITEM_IN " .
								"ON SUB_IN.sub_id = ITEM_IN.sub_id) INNER JOIN HAS_READ ON HAS_READ.item_id = ITEM_IN.item_id", "DUMMY"), 
							  "user_id = {$_SESSION['user_id']} AND deleted != 1", $order, "", $group));

		return $menu_reads;
	}	

	private function get_access_restrictions() {

		$select = array(array("parent_id", "rank"), array("dir_id"), array("allow"));

		$from = array("DIRECTORY_TREE", "DIRECTORY", "ACCESS_RULE");

		$where = "DIRECTORY_TREE.child_id = ACCESS_RULE.dir_id AND
				  DIRECTORY_TREE.child_id = DIRECTORY.dir_id AND 
				  ACCESS_RULE.action_id = 1 AND 
				  (";

		if ($_SESSION['user_id']) {
			for ($i = 0; $i < count($_SESSION['user_groups']); $i++)
				$groups .= $_SESSION['user_groups'][$i].",";
			$groups .= "-1";
			$where .= "ACCESS_RULE.user_id = {$_SESSION['user_id']} OR 
					   ACCESS_RULE.usergroup_id IN ($groups) OR ";
		}
		$where .= "ACCESS_RULE.ipstring LIKE '".$_SERVER["REMOTE_ADDR"]." - ".$_SERVER["HTTP_X_FORWARDED_FOR"]."' OR 
				   ACCESS_RULE.guest > 0\n\t)";
		
		$order = "DIRECTORY_TREE.parent_id ASC, DIRECTORY_TREE.rank ASC, ACCESS_RULE.rank ASC";
		
		$sql = $this->db_access->db_query_select($select, $from, $where, $order);
		
		return $this->db_access->db_do_query($sql);
	}

	private function add_plain_info($row) {
		$this->menu[$row['dir_id']] = $row;
	}

	private function add_ignore_info($row, $ignored) {
			if ($_SESSION['user_id'] and $ignored[$row['dir_id']]) 
				$this->menu[$row['dir_id']]['ignored'] = 1;
	}

	private function add_access_info($row, $row_access, $menu_access) {
		$this->menu[$row['dir_id']]['access'] = "INHERIT";
		if ($row_access['dir_id'] == $row['dir_id']) {
			$this->menu[$row['dir_id']]['access'] = $row_access['allow'] ? "ALLOW" : "DENY";
			while ($row_access['dir_id'] == $row['dir_id']) {
				$row_access = $this->db_access->db_fetch_array($menu_access); 
			}
		}
	}

	private function add_to_parent_dir($row) {
		$this->menu[$row['parent_id']]['children'][$row['rank']] = $row['dir_id'];
		$this->menu[$row['child_id']]['parents'] = array();
		$this->menu[$row['child_id']]['children'] = array();
	}

	private function add_parents() {
		$parentstuff = $this->db_access->db_do_query($this->db_access->db_query_select(array(array("*")), array("DIRECTORY_TREE"), 1));
		while ($p = $this->db_access->db_fetch_array($parentstuff)) {
			if ($p['child_id']) {
				array_push($this->menu[$p['child_id']]['parents'], $p['parent_id']);
			}
		}
	}

	private function add_what_has_been_read_info($menu_reads, $menu_items) {
		while ($row_reads = $this->db_access->db_fetch_array($menu_reads)) {
			$this->menu[$row_reads['child_id']]['read_items'] = $row_reads['read_count'];
		}
		while ($row_items = $this->db_access->db_fetch_array($menu_items)) {
			$this->menu[$row_items['child_id']]['items'] = $row_items['items'];
			$this->menu[$row_items['child_id']]['new_items'] = $this->menu[$row_items['child_id']]['items'] 
															 - $this->menu[$row_items['child_id']]['read_items'];
		}
	}

	private function add_ignore_info2() {
		$menu_ignore = $this->db_access->db_do_query($this->db_access->db_query_select(array(("*")), array("IGNORE_DIR"), 
								 "user_id = {$_SESSION['user_id']}"));
		while ($ri = $this->db_access->db_fetch_array($menu_ignore)) {
			$this->menu = $this->toolbox->util_set_ignored($ri['dir_id'], $this->menu);
		}
	}
}

?>
